<template>
  <el-select
    v-model="val"
    :multiple="multiple"
    filterable
    :remote="remote"
    reserve-keyword
    :placeholder="placeholder"
    remote-show-suffix
    :remote-method="remoteMethod"
    :loading="loading"
    clearable
    @change="onChange"
  >
    <el-option
      v-for="item in options"
      :key="item[keyprops.value]"
      :label="item[keyprops.label]"
      :value="item[keyprops.value]"
    />
  </el-select>
</template>

<script lang="ts" setup>
import { onMounted, ref, watch } from "vue";

const props = defineProps({
  modelValue: {
    type: [Array, String, Number],
    default: ""
  },
  /* 是否多选 */
  multiple: {
    default: false,
    type: Boolean
  },
  /* 请求的promise对象 */
  httpfn: {
    default: null
  },
  /* 自定义数据处理 */
  datafn: {
    default: null
  },
  /* 需要请求的参数：组件内部 */
  params: {
    default: () => ({})
  },
  /* 搜索的时候，输入的值key */
  paramsKey: {
    default: ""
  },
  /* 绑定的key-value值 */
  keyprops: {
    default: () => ({ label: "name", value: "id" })
  },
  /* 是否需要分页 可传入对象{size: 100, current: 1} | 不传则为false,不分页*/
  pagination: {
    default: false,
    type: [Boolean, Object]
  },
  /* 初始化是否即可请求列表 */
  immediately: {
    default: false
  },
  placeholder: {
    default: "请选择"
  }
});

const { multiple, httpfn, datafn, keyprops } = props;

const loading = ref(false);
const options = ref([]);
const remote = ref(true);
/* 如果立马请求数据，并且请求全部数据 */
if (props.immediately && !props.pagination) {
  remote.value = false;
}
const initData = (query: string = "") => {
  loading.value = true;
  let params: Object = { [props.paramsKey]: query };
  if (props.pagination) {
    params = { ...params, ...(props.pagination as Object) };
  }

  httpfn(params)
    .then(res => {
      // 自定义处理列表
      let list = [];
      if (datafn) {
        list = datafn(res);
      } else {
        list = [...res.data];
      }
      options.value = [...list];
      loading.value = false;
    })
    .catch(() => {
      loading.value = false;
    });
};
if (props.immediately) {
  onMounted(() => {
    initData();
  });
}
defineExpose({ initData });

// 搜索请求
const remoteMethod = query => {
  // 已经请求了全部数据，则不需要再远程搜索
  if (props.pagination && remote.value) {
    initData(query);
  }
};

/* 双向绑定 */
const val: any = ref("");
const emit = defineEmits(["update:modelValue", "change"]);
const onChange = val => {
  emit("update:modelValue", val);
  emit(
    "change",
    val,
    options.value.find(item => item[props.keyprops.value] == val)
  );
};
val.value = props.modelValue;
watch(
  () => props.modelValue,
  (newVal, oldVal) => {
    val.value = newVal;
  }
);
</script>
